#ifndef __GfxDriver_WGL_WGLShader_h__
#define __GfxDriver_WGL_WGLShader_h__


#include "GfxDriver/Shader.h"

#include "GfxDriver/WGL/GLInclude.h"

#include <vector>
#include <map>

namespace Orca {

	class GfxDriver;

	//--------------------------------------------------------------------------
	class WGLVertexProgram : public VertexProgram {
	
	public:
		static WGLVertexProgram* create(
			 GfxDriver *gfxDriver
			,const uint8* data);

		WGLVertexProgram(GLuint glHandle);
		~WGLVertexProgram();

		virtual unsigned int getAPIHandle(); 

	private:
		GLuint mGLHandle;

	};

	//--------------------------------------------------------------------------
	class WGLFragmentProgram : public FragmentProgram {

	public:
		static WGLFragmentProgram* create(
			 GfxDriver *gfxDriver
			,const uint8* data);

		WGLFragmentProgram(GLuint glHandle);
		~WGLFragmentProgram();

		virtual unsigned int getAPIHandle(); 

	private:
		GLuint mGLHandle;

	};

	//--------------------------------------------------------------------------
	class WGLShader : public Shader {

	public:
		static WGLShader* create(
			 GfxDriver *gfxDriver
			,VertexProgram *vp
			,FragmentProgram *fp);

		WGLShader(GfxDriver *gfxDriver, GLuint glHandle);
		virtual ~WGLShader();

		virtual void beginRender();
		virtual void endRender();

		virtual void beginBinding();
		virtual void endBinding();

		virtual void bindFloat(const Str &name, float val);
		virtual void bindVec2(const Str &name, const vec2 &val);
		virtual void bindVec3(const Str &name, const vec3 &val);
		virtual void bindVec4(const Str &name, const vec4 &val);
		virtual void bindMtx4(const Str &name, const mtx44 &val);

		virtual void bindFloatArray(const Str &name, const float *val, uint32 cnt);
		virtual void bindVec2Array(const Str &name, const vec2 *val, uint32 cnt);
		virtual void bindVec3Array(const Str &name, const vec3 *val, uint32 cnt);
		virtual void bindVec4Array(const Str &name, const vec4 *val, uint32 cnt);
		virtual void bindMtx4Array(const Str &name, const mtx44 *val, uint32 cnt);

		virtual void bindTexture(const Str &name, Texture *tex);

	private:
		GfxDriver *mGfxDriver;
		GLuint mGLHandle;

		typedef std::map< Str, uint32 > TSamplerMapping;
		TSamplerMapping mSamplerMapping;
		std::vector<Texture*> mSamplerTexture;

		GLint _getUniformLocation(const Str &name);
	};

}

#endif	// __GfxDriver_WGL_WGLShader_h__